home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Main.bin / List.java < prev    next >
Text File  |  1998-09-22  |  30KB  |  927 lines

  1. /*
  2.  * @(#)List.java    1.60 98/08/13
  3.  *
  4.  * Copyright 1995-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  * 
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14. package java.awt;
  15.  
  16. import java.util.Vector;
  17. import java.awt.peer.ListPeer;
  18. import java.awt.event.*;
  19. import java.io.ObjectOutputStream;
  20. import java.io.ObjectInputStream;
  21. import java.io.IOException;
  22.  
  23.  
  24. /**
  25.  * The <code>List</code> component presents the user with a 
  26.  * scrolling list of text items. The list can be set up so that  
  27.  * the user can choose either one item or multiple items. 
  28.  * <p>
  29.  * For example, the code . . .
  30.  * <p>
  31.  * <hr><blockquote><pre>
  32.  * List lst = new List(4, false);
  33.  * lst.add("Mercury");
  34.  * lst.add("Venus");
  35.  * lst.add("Earth");
  36.  * lst.add("JavaSoft");
  37.  * lst.add("Mars");
  38.  * lst.add("Jupiter");
  39.  * lst.add("Saturn");
  40.  * lst.add("Uranus");
  41.  * lst.add("Neptune");
  42.  * lst.add("Pluto");
  43.  * cnt.add(lst);
  44.  * </pre></blockquote><hr>
  45.  * <p>
  46.  * where <code>cnt</code> is a container, produces the following 
  47.  * scrolling list:
  48.  * <p>
  49.  * <img src="images-awt/List-1.gif" 
  50.  * ALIGN=center HSPACE=10 VSPACE=7> 
  51.  * <p>
  52.  * Clicking on an item that isn't selected selects it. Clicking on 
  53.  * an item that is already selected deselects it. In the preceding 
  54.  * example, only one item from the scrolling list can be selected 
  55.  * at a time, since the second argument when creating the new scrolling 
  56.  * list is <code>false</code>. Selecting an item causes any other 
  57.  * selected item to be automatically deselected. 
  58.  * <p>
  59.  * Beginning with Java 1.1, the Abstract Window Toolkit 
  60.  * sends the <code>List</code> object all mouse, keyboard, and focus events 
  61.  * that occur over it. (The old AWT event model is being maintained
  62.  * only for backwards compatibility, and its use is discouraged.)
  63.  * <p>
  64.  * When an item is selected or deselected, AWT sends an instance  
  65.  * of <code>ItemEvent</code> to the list.
  66.  * When the user double-clicks on an item in a scrolling list,  
  67.  * AWT sends an instance of <code>ActionEvent</code> to the 
  68.  * list following the item event. AWT also generates an action event 
  69.  * when the user presses the return key while an item in the 
  70.  * list is selected.
  71.  * <p>
  72.  * If an application wants to perform some action based on an item 
  73.  * in this list being selected or activated, it should implement 
  74.  * <code>ItemListener</code> or <code>ActionListener</code> 
  75.  * as appropriate and register the new listener to receive 
  76.  * events from this list. 
  77.  * <p>
  78.  * For multiple-selection scrolling lists, it is considered a better 
  79.  * user interface to use an external gesture (such as clicking on a 
  80.  * button) to trigger the action. 
  81.  * @version     1.60, 08/13/98
  82.  * @author     Sami Shaio
  83.  * @see         java.awt.event.ItemEvent
  84.  * @see         java.awt.event.ItemListener
  85.  * @see         java.awt.event.ActionEvent
  86.  * @see         java.awt.event.ActionListener
  87.  * @since       JDK1.0
  88.  */
  89. public class List extends Component implements ItemSelectable {
  90.     Vector    items = new Vector();
  91.     int        rows = 0;
  92.     boolean    multipleMode = false;
  93.     int        selected[] = new int[0];
  94.     int        visibleIndex = -1;
  95.  
  96.     transient ActionListener actionListener;
  97.     transient ItemListener itemListener;
  98.  
  99.     private static final String base = "list";
  100.     private static int nameCounter = 0;
  101.  
  102.     /*
  103.      * JDK 1.1 serialVersionUID 
  104.      */
  105.      private static final long serialVersionUID = -3304312411574666869L;
  106.  
  107.     /**
  108.      * Creates a new scrolling list. Initially there are no visible 
  109.      * lines, and only one item can be selected from the list. 
  110.      * @since       JDK1.0
  111.      */
  112.     public List() {
  113.     this(0, false);
  114.     }
  115.  
  116.     /**
  117.      * Creates a new scrolling list initialized with the specified 
  118.      * number of visible lines. By default, multiple selections are
  119.      * not allowed.
  120.      * @param       rows the number of items to show.
  121.      * @since       JDK1.1
  122.      */
  123.     public List(int rows) {
  124.         this(rows, false);
  125.     }
  126.  
  127.     /** 
  128.      * The default number of visible rows is 4.  A list with
  129.      * zero rows is unusable and unsightly.
  130.      */
  131.     final static int     DEFAULT_VISIBLE_ROWS = 4;
  132.  
  133.     /**
  134.      * Creates a new scrolling list initialized to display the specified 
  135.      * number of rows. If the value of <code>multipleMode</code> is 
  136.      * <code>true</code>, then the user can select multiple items from  
  137.      * the list. If it is <code>false</code>, only one item at a time 
  138.      * can be selected. 
  139.      * @param       rows   the number of items to show.
  140.      * @param       multipleMode   if <code>true</code>,
  141.      *                     then multiple selections are allowed; 
  142.      *                     otherwise, only one item can be selected at a time.
  143.      * @since       JDK1.0
  144.      */
  145.     public List(int rows, boolean multipleMode) {
  146.     this.rows = (rows != 0) ? rows : DEFAULT_VISIBLE_ROWS; 
  147.     this.multipleMode = multipleMode;
  148.     }
  149.  
  150.     /**
  151.      * Construct a name for this component.  Called by getName() when the
  152.      * name is null.
  153.      */
  154.     String constructComponentName() {
  155.         return base + nameCounter++;
  156.     }
  157.  
  158.     /**
  159.      * Creates the peer for the list.  The peer allows us to modify the
  160.      * list's appearance without changing its functionality.
  161.      */
  162.     public void addNotify() {
  163.         synchronized (getTreeLock()) {
  164.         if (peer == null)
  165.             peer = getToolkit().createList(this);
  166.         super.addNotify();
  167.         visibleIndex = -1;
  168.         }
  169.     }
  170.  
  171.     /**
  172.      * Removes the peer for this list.  The peer allows us to modify the
  173.      * list's appearance without changing its functionality.
  174.      */
  175.     public void removeNotify() {
  176.         synchronized (getTreeLock()) {
  177.         ListPeer peer = (ListPeer)this.peer;
  178.         if (peer != null) {
  179.         selected = peer.getSelectedIndexes();
  180.         }
  181.             super.removeNotify();
  182.     }
  183.     }
  184.     
  185.     /**
  186.      * Gets the number of items in the list.
  187.      * @return     the number of items in the list.
  188.      * @see        java.awt.List#getItem
  189.      * @since      JDK1.1
  190.      */
  191.     public int getItemCount() {
  192.     return countItems();
  193.     }
  194.     
  195.     /**
  196.      * @deprecated As of JDK version 1.1,
  197.      * replaced by <code>getItemCount()</code>.
  198.      */
  199.     public int countItems() {
  200.     return items.size();
  201.     }
  202.  
  203.     /**
  204.      * Gets the item associated with the specified index.
  205.      * @return       an item that is associated with 
  206.      *                    the specified index.
  207.      * @param        index the position of the item.
  208.      * @see          java.awt.List#getItemCount
  209.      * @since        JDK1.0
  210.      */
  211.     public String getItem(int index) {
  212.     return (String)items.elementAt(index);
  213.     }
  214.  
  215.     /**
  216.      * Gets the items in the list.
  217.      * @return       a string array containing items of the list.
  218.      * @see          java.awt.List#select
  219.      * @see          java.awt.List#deselect
  220.      * @see          java.awt.List#isIndexSelected
  221.      * @since        JDK1.1
  222.      */
  223.     public synchronized String[] getItems() {
  224.     String itemCopies[] = new String[items.size()];
  225.         items.copyInto(itemCopies);
  226.     return itemCopies;
  227.     }
  228.  
  229.     /**
  230.      * Adds the specified item to the end of scrolling list.
  231.      * @param item the item to be added.
  232.      * @since JDK1.1
  233.      */
  234.     public void add(String item) {
  235.     addItem(item);
  236.     }
  237.  
  238.     /**
  239.      * 
  240.      */
  241.     public void addItem(String item) {
  242.     addItem(item, -1);
  243.     }
  244.  
  245.     /**
  246.      * Adds the specified item to the end of the scrolling list.
  247.      * The index is zero-based. If value of the index is 
  248.      * <code>-1</code> then the item is added to the end. 
  249.      * If value of the index is greater than the number of 
  250.      * items in the list, the item is added at the end. 
  251.      * @param       item   the item to be added.
  252.      * @param       index  the position at which to add the item. 
  253.      * @since       JDK1.1
  254.      */
  255.     public void add(String item, int index) {
  256.     addItem(item, index);
  257.     }
  258.  
  259.     /**
  260.      * 
  261.      */
  262.     public synchronized void addItem(String item, int index) {
  263.     if (index < -1 || index >= items.size()) {
  264.         index = -1;
  265.     }
  266.     if (index == -1) {
  267.         items.addElement(item);
  268.     } else {
  269.         items.insertElementAt(item, index);
  270.     }
  271.     ListPeer peer = (ListPeer)this.peer;
  272.     if (peer != null) {
  273.         peer.addItem(item, index);
  274.     }
  275.     }
  276.  
  277.     /**
  278.      * Replaces the item at the specified index in the scrolling list
  279.      * with the new string.
  280.      * @param       newValue   a new string to replace an existing item.
  281.      * @param       index      the position of the item to replace.
  282.      * @since       JDK1.0
  283.      */
  284.     public synchronized void replaceItem(String newValue, int index) {
  285.     remove(index);
  286.     add(newValue, index);
  287.     }
  288.  
  289.     /**
  290.      * Removes all items from this list.
  291.      * @see #remove
  292.      * @see #delItems
  293.      * @since JDK1.1
  294.      */
  295.     public void removeAll() {
  296.     clear();
  297.     }
  298.  
  299.     /**
  300.      * @deprecated As of JDK version 1.1,
  301.      * replaced by <code>removeAll()</code>.
  302.      */
  303.     public synchronized void clear() {
  304.     ListPeer peer = (ListPeer)this.peer;
  305.     if (peer != null) {
  306.         peer.clear();
  307.     }
  308.     items = new Vector();
  309.     selected = new int[0];
  310.     }
  311.  
  312.     /**
  313.      * Removes the first occurrence of an item from the list.
  314.      * @param        item  the item to remove from the list.
  315.      * @exception    IllegalArgumentException  
  316.      *                     if the item doesn't exist in the list.
  317.      * @since        JDK1.1
  318.      */
  319.     public synchronized void remove(String item) {
  320.         int index = items.indexOf(item);
  321.         if (index < 0) {
  322.         throw new IllegalArgumentException("item " + item +
  323.                            " not found in list");
  324.     } else {
  325.         remove(index);
  326.     }
  327.     }
  328.  
  329.     /**
  330.      * Remove the item at the specified position  
  331.      * from this scrolling list. 
  332.      * @param      position   the index of the item to delete.
  333.      * @see        java.awt.List#add(String, int)
  334.      * @since      JDK1.1
  335.      */
  336.     public void remove(int position) {
  337.     delItem(position);
  338.     }
  339.  
  340.     /**
  341.      * Removes the item at the specified position from this list.
  342.      */
  343.     public void delItem(int position) {
  344.     delItems(position, position);
  345.     }
  346.  
  347.     /**
  348.      * Gets the index of the selected item on the list, 
  349.      * @return        the index of the selected item, or 
  350.      *                     <code>-1</code> if no item is selected,
  351.      *                     or if more that one item is selected.
  352.      * @see           java.awt.List#select
  353.      * @see           java.awt.List#deselect
  354.      * @see           java.awt.List#isIndexSelected
  355.      * @since         JDK1.0
  356.      */
  357.     public synchronized int getSelectedIndex() {
  358.     int sel[] = getSelectedIndexes();
  359.     return (sel.length == 1) ? sel[0] : -1;
  360.     }
  361.  
  362.     /**
  363.      * Gets the selected indexes on the list.
  364.      * @return        an array of the selected indexes 
  365.      *                            of this scrolling list. 
  366.      * @see           java.awt.List#select
  367.      * @see           java.awt.List#deselect
  368.      * @see           java.awt.List#isIndexSelected
  369.      * @since         JDK1.0
  370.      */
  371.     public synchronized int[] getSelectedIndexes() {
  372.     ListPeer peer = (ListPeer)this.peer;
  373.     if (peer != null) {
  374.         selected = ((ListPeer)peer).getSelectedIndexes();
  375.     }
  376.     return selected;
  377.     }
  378.  
  379.     /**
  380.      * Get the selected item on this scrolling list.
  381.      * @return        the selected item on the list, 
  382.      *                     or null if no item is selected.
  383.      * @see           java.awt.List#select
  384.      * @see           java.awt.List#deselect
  385.      * @see           java.awt.List#isIndexSelected
  386.      * @since         JDK1.0
  387.      */
  388.     public synchronized String getSelectedItem() {
  389.     int index = getSelectedIndex();
  390.     return (index < 0) ? null : getItem(index);
  391.     }
  392.  
  393.     /**
  394.      * Get the selected items on this scrolling list.
  395.      * @return        an array of the selected items 
  396.      *                            on this scrolling list.
  397.      * @see           java.awt.List#select
  398.      * @see           java.awt.List#deselect
  399.      * @see           java.awt.List#isIndexSelected
  400.      * @since         JDK1.0
  401.      */
  402.     public synchronized String[] getSelectedItems() {
  403.     int sel[] = getSelectedIndexes();
  404.     String str[] = new String[sel.length];
  405.     for (int i = 0 ; i < sel.length ; i++) {
  406.         str[i] = getItem(sel[i]);
  407.     }
  408.     return str;
  409.     }
  410.  
  411.     /**
  412.      * Returns the selected items on the list in an array of Objects.
  413.      * @see ItemSelectable
  414.      */
  415.     public Object[] getSelectedObjects() {
  416.         return getSelectedItems();
  417.     }
  418.  
  419.     /**
  420.      * Selects the item at the specified index in the scrolling list.
  421.      * @param        index the position of the item to select.
  422.      * @see          java.awt.List#getSelectedItem
  423.      * @see          java.awt.List#deselect
  424.      * @see          java.awt.List#isIndexSelected
  425.      * @since        JDK1.0
  426.      */
  427.     public void select(int index) { 
  428.         // Bug #4059614: select can't be synchronized while calling the peer, 
  429.         // because it is called from the Window Thread.  It is sufficient to 
  430.         // synchronize the code that manipulates 'selected' except for the 
  431.         // case where the peer changes.  To handle this case, we simply 
  432.         // repeat the selection process. 
  433.          
  434.         ListPeer peer; 
  435.         do { 
  436.             peer = (ListPeer)this.peer; 
  437.             if (peer != null) { 
  438.                 peer.select(index); 
  439.                 return; 
  440.             } 
  441.              
  442.             synchronized(this) 
  443.             { 
  444.                 boolean alreadySelected = false; 
  445.  
  446.                 for (int i = 0 ; i < selected.length ; i++) { 
  447.                     if (selected[i] == index) { 
  448.                         alreadySelected = true; 
  449.                         break; 
  450.                     } 
  451.                 } 
  452.  
  453.                 if (!alreadySelected) { 
  454.                     if (!multipleMode) { 
  455.                         selected = new int[1]; 
  456.                         selected[0] = index; 
  457.                     } else { 
  458.                         int newsel[] = new int[selected.length + 1]; 
  459.                         System.arraycopy(selected, 0, newsel, 0, 
  460.                                          selected.length); 
  461.                         newsel[selected.length] = index; 
  462.                         selected = newsel; 
  463.                     } 
  464.                 } 
  465.             } 
  466.         } while (peer != this.peer); 
  467.     } 
  468.  
  469.     /**
  470.      * Deselects the item at the specified index.
  471.      * <p>
  472.      * If the item at the specified index is not selected, or if the 
  473.      * index is out of range, then the operation is ignored. 
  474.      * @param        index the position of the item to deselect.
  475.      * @see          java.awt.List#select
  476.      * @see          java.awt.List#getSelectedItem
  477.      * @see          java.awt.List#isIndexSelected
  478.      * @since        JDK1.0
  479.      */
  480.     public synchronized void deselect(int index) {
  481.     ListPeer peer = (ListPeer)this.peer;
  482.     if (peer != null) {
  483.         peer.deselect(index);
  484.     }
  485.  
  486.     for (int i = 0 ; i < selected.length ; i++) {
  487.         if (selected[i] == index) {
  488.         int newsel[] = new int[selected.length - 1];
  489.         System.arraycopy(selected, 0, newsel, 0, i);
  490.         System.arraycopy(selected, i+1, newsel, i, selected.length - (i+1));
  491.         selected = newsel;
  492.         return;
  493.         }
  494.     }
  495.     }
  496.  
  497.     /**
  498.      * Determines if the specified item in this scrolling list is 
  499.      * selected. 
  500.      * @param      index   the item to be checked.
  501.      * @return     <code>true</code> if the specified item has been
  502.      *                       selected; <code>false</code> otherwise.
  503.      * @see        java.awt.List#select
  504.      * @see        java.awt.List#deselect
  505.      * @since      JDK1.1
  506.      */
  507.     public boolean isIndexSelected(int index) {
  508.     return isSelected(index);
  509.     }
  510.  
  511.     /**
  512.      * @deprecated As of JDK version 1.1,
  513.      * replaced by <code>isIndexSelected(int)</code>.
  514.      */
  515.     public boolean isSelected(int index) {
  516.     int sel[] = getSelectedIndexes();
  517.     for (int i = 0 ; i < sel.length ; i++) {
  518.         if (sel[i] == index) {
  519.         return true;
  520.         }
  521.     }
  522.     return false;
  523.     }
  524.  
  525.     /**
  526.      * Get the number of visible lines in this list.
  527.      * @return     the number of visible lines in this scrolling list.
  528.      * @since      JDK1.0
  529.      */
  530.     public int getRows() {
  531.     return rows;
  532.     }
  533.  
  534.     /**
  535.      * Determines whether this list allows multiple selections.
  536.      * @return     <code>true</code> if this list allows multiple 
  537.      *                 selections; otherwise, <code>false</code>.
  538.      * @see        java.awt.List#setMultipleMode
  539.      * @since      JDK1.1
  540.      */
  541.     public boolean isMultipleMode() {
  542.     return allowsMultipleSelections();
  543.     }
  544.  
  545.     /**
  546.      * @deprecated As of JDK version 1.1,
  547.      * replaced by <code>isMultipleMode()</code>.
  548.      */
  549.     public boolean allowsMultipleSelections() {
  550.     return multipleMode;
  551.     }
  552.  
  553.     /**
  554.      * Sets the flag that determines whether this list 
  555.      * allows multiple selections.
  556.      * @param       b   if <code>true</code> then multiple selections
  557.      *                      are allowed; otherwise, only one item from
  558.      *                      the list can be selected at once.
  559.      * @see         java.awt.List#isMultipleMode
  560.      * @since       JDK1.1
  561.      */
  562.     public void setMultipleMode(boolean b) {
  563.         setMultipleSelections(b);
  564.     }
  565.  
  566.     /**
  567.      * @deprecated As of JDK version 1.1,
  568.      * replaced by <code>setMultipleMode(boolean)</code>.
  569.      */
  570.     public synchronized void setMultipleSelections(boolean b) {
  571.     if (b != multipleMode) {
  572.         multipleMode = b;
  573.         ListPeer peer = (ListPeer)this.peer;
  574.         if (peer != null) {
  575.         peer.setMultipleSelections(b);
  576.         }
  577.     }
  578.     }
  579.  
  580.     /**
  581.      * Gets the index of the item that was last made visible by 
  582.      * the method <code>makeVisible</code>.
  583.      * @return      the index of the item that was last made visible.
  584.      * @see         java.awt.List#makeVisible
  585.      * @since       JDK1.0
  586.      */
  587.     public int getVisibleIndex() {
  588.     return visibleIndex;
  589.     }
  590.  
  591.     /**
  592.      * Makes the item at the specified index visible. 
  593.      * @param       index    the position of the item.
  594.      * @see         java.awt.List#getVisibleIndex
  595.      * @since       JDK1.0
  596.      */
  597.     public synchronized void makeVisible(int index) {
  598.     visibleIndex = index;
  599.     ListPeer peer = (ListPeer)this.peer;
  600.     if (peer != null) {
  601.         peer.makeVisible(index);
  602.     }
  603.     }
  604.  
  605.     /**
  606.      * Gets the preferred dimensions for a list with the specified
  607.      * number of rows.  
  608.      * @param      rows    number of rows in the list.
  609.      * @return     the preferred dimensions for displaying this scrolling list.
  610.      * @see        java.awt.Component#getPreferredSize
  611.      * @since      JDK1.1
  612.      */
  613.     public Dimension getPreferredSize(int rows) {
  614.     return preferredSize(rows);
  615.     }
  616.  
  617.     /**
  618.      * @deprecated As of JDK version 1.1,
  619.      * replaced by <code>getPreferredSize(int)</code>.
  620.      */
  621.     public Dimension preferredSize(int rows) {
  622.         synchronized (getTreeLock()) {
  623.           ListPeer peer = (ListPeer)this.peer;
  624.          return (peer != null) ?
  625.                  peer.preferredSize(rows) :
  626.                  super.preferredSize();
  627.       }
  628.     }
  629.  
  630.     /**
  631.      * Gets the preferred size of this scrolling list.  
  632.      * @return     the preferred dimensions for displaying this scrolling list.
  633.      * @see        java.awt.Component#getPreferredSize
  634.      * @since      JDK1.1 
  635.      */
  636.     public Dimension getPreferredSize() {
  637.     return preferredSize();
  638.     }
  639.  
  640.     /**
  641.      * @deprecated As of JDK version 1.1,
  642.      * replaced by <code>getPreferredSize()</code>.
  643.      */
  644.     public Dimension preferredSize() {
  645.     synchronized (getTreeLock()) {
  646.         return (rows > 0) ?
  647.                preferredSize(rows) :
  648.                super.preferredSize();
  649.     }
  650.     }
  651.  
  652.     /**
  653.      * Gets the minumum dimensions for a list with the specified
  654.      * number of rows.
  655.      * @param      rows    number of rows in the list.
  656.      * @return     the minimum dimensions for displaying this scrolling list.
  657.      * @see        java.awt.Component#getMinimumSize
  658.      * @since      JDK1.1
  659.      */
  660.     public Dimension getMinimumSize(int rows) {
  661.     return minimumSize(rows);
  662.     }
  663.  
  664.     /**
  665.      * @deprecated As of JDK version 1.1,
  666.      * replaced by <code>getMinimumSize(int)</code>.
  667.      */
  668.     public Dimension minimumSize(int rows) {
  669.       synchronized (getTreeLock()) {
  670.           ListPeer peer = (ListPeer)this.peer;
  671.          return (peer != null) ?
  672.                         peer.minimumSize(rows) :
  673.                 super.minimumSize();
  674.       }
  675.     }
  676.  
  677.     /**
  678.      * Determines the minimum size of this scrolling list. 
  679.      * @return       the minimum dimensions needed 
  680.      *                        to display this scrolling list.
  681.      * @see          java.awt.Component#getMinimumSize()
  682.      * @since        JDK1.1
  683.      */
  684.     public Dimension getMinimumSize() {
  685.     return minimumSize();
  686.     }
  687.  
  688.     /**
  689.      * @deprecated As of JDK version 1.1,
  690.      * replaced by <code>getMinimumSize()</code>.
  691.      */
  692.     public Dimension minimumSize() {
  693.     synchronized (getTreeLock()) {
  694.         return (rows > 0) ? minimumSize(rows) : super.minimumSize();
  695.     }
  696.     }
  697.  
  698.     /**
  699.      * Adds the specified item listener to receive item events from
  700.      * this list.
  701.      * @param         l the item listener.
  702.      * @see           java.awt.event.ItemEvent
  703.      * @see           java.awt.event.ItemListener
  704.      * @see           java.awt.List#removeItemListener
  705.      * @since         JDK1.1
  706.      */ 
  707.     public synchronized void addItemListener(ItemListener l) {
  708.         itemListener = AWTEventMulticaster.add(itemListener, l);
  709.         newEventsOnly = true;
  710.     }
  711.  
  712.     /**
  713.      * Removes the specified item listener so that it no longer 
  714.      * receives item events from this list. 
  715.      * @param         l the item listener.
  716.      * @see           java.awt.event.ItemEvent
  717.      * @see           java.awt.event.ItemListener
  718.      * @see           java.awt.List#addItemListener
  719.      * @since         JDK1.1
  720.      */ 
  721.     public synchronized void removeItemListener(ItemListener l) {
  722.         itemListener = AWTEventMulticaster.remove(itemListener, l);
  723.     }
  724.  
  725.     /**
  726.      * Adds the specified action listener to receive action events from
  727.      * this list. Action events occur when a user double-clicks
  728.      * on a list item.
  729.      * @param         l the action listener.
  730.      * @see           java.awt.event.ActionEvent
  731.      * @see           java.awt.event.ActionListener
  732.      * @see           java.awt.List#removeActionListener
  733.      * @since         JDK1.1
  734.      */ 
  735.     public synchronized void addActionListener(ActionListener l) {
  736.     actionListener = AWTEventMulticaster.add(actionListener, l);
  737.         newEventsOnly = true;    
  738.     }
  739.  
  740.     /**
  741.      * Removes the specified action listener so that it no longer 
  742.      * receives action events from this list. Action events 
  743.      * occur when a user double-clicks on a list item.
  744.      * @param         l     the action listener.
  745.      * @see           java.awt.event.ActionEvent
  746.      * @see           java.awt.event.ActionListener
  747.      * @see           java.awt.List#addActionListener
  748.      * @since         JDK1.1
  749.      */ 
  750.     public synchronized void removeActionListener(ActionListener l) {
  751.     actionListener = AWTEventMulticaster.remove(actionListener, l);
  752.     }
  753.  
  754.     // REMIND: remove when filtering is done at lower level
  755.     boolean eventEnabled(AWTEvent e) {
  756.         switch(e.id) {
  757.           case ActionEvent.ACTION_PERFORMED:
  758.             if ((eventMask & AWTEvent.ACTION_EVENT_MASK) != 0 ||
  759.                 actionListener != null) {
  760.                 return true;
  761.             } 
  762.             return false;
  763.           case ItemEvent.ITEM_STATE_CHANGED:
  764.             if ((eventMask & AWTEvent.ITEM_EVENT_MASK) != 0 ||
  765.                 itemListener != null) {
  766.                 return true;
  767.             }
  768.             return false;
  769.           default:
  770.             break;
  771.         } 
  772.         return super.eventEnabled(e);
  773.     }          
  774.  
  775.     /**
  776.      * Processes events on this scrolling list. If an event is 
  777.      * an instance of <code>ItemEvent</code>, it invokes the 
  778.      * <code>processItemEvent</code> method. Else, if the 
  779.      * event is an instance of <code>ActionEvent</code>, 
  780.      * it invokes <code>processActionEvent</code>.
  781.      * If the event is not an item event or an action event,
  782.      * it invokes <code>processEvent</code> on the superclass.
  783.      * @param        e the event.
  784.      * @see          java.awt.event.ActionEvent
  785.      * @see          java.awt.event.ItemEvent
  786.      * @see          java.awt.List#processActionEvent
  787.      * @see          java.awt.List#processItemEvent
  788.      * @since        JDK1.1
  789.      */
  790.     protected void processEvent(AWTEvent e) {
  791.         if (e instanceof ItemEvent) {
  792.             processItemEvent((ItemEvent)e);
  793.             return;
  794.         } else if (e instanceof ActionEvent) {
  795.             processActionEvent((ActionEvent)e);
  796.             return;
  797.         }
  798.     super.processEvent(e);
  799.     }
  800.  
  801.     /** 
  802.      * Processes item events occurring on this list by
  803.      * dispatching them to any registered 
  804.      * <code>ItemListener</code> objects. 
  805.      * <p>
  806.      * This method is not called unless item events are 
  807.      * enabled for this component. Item events are enabled 
  808.      * when one of the following occurs:
  809.      * <p><ul>
  810.      * <li>An <code>ItemListener</code> object is registered 
  811.      * via <code>addItemListener</code>.
  812.      * <li>Item events are enabled via <code>enableEvents</code>.
  813.      * </ul>
  814.      * @param       e the item event.
  815.      * @see         java.awt.event.ItemEvent
  816.      * @see         java.awt.event.ItemListener
  817.      * @see         java.awt.List#addItemListener
  818.      * @see         java.awt.Component#enableEvents
  819.      * @since       JDK1.1
  820.      */  
  821.     protected void processItemEvent(ItemEvent e) {
  822.         if (itemListener != null) {
  823.             itemListener.itemStateChanged(e);
  824.         }
  825.     }
  826.  
  827.     /** 
  828.      * Processes action events occurring on this component 
  829.      * by dispatching them to any registered 
  830.      * <code>ActionListener</code> objects.
  831.      * <p>
  832.      * This method is not called unless action events are 
  833.      * enabled for this component. Action events are enabled 
  834.      * when one of the following occurs:
  835.      * <p><ul>
  836.      * <li>An <code>ActionListener</code> object is registered 
  837.      * via <code>addActionListener</code>.
  838.      * <li>Action events are enabled via <code>enableEvents</code>.
  839.      * </ul>
  840.      * @param       e the action event.
  841.      * @see         java.awt.event.ActionEvent
  842.      * @see         java.awt.event.ActionListener
  843.      * @see         java.awt.List#addActionListener
  844.      * @see         java.awt.Component#enableEvents
  845.      * @since       JDK1.1
  846.      */  
  847.     protected void processActionEvent(ActionEvent e) {
  848.         if (actionListener != null) {
  849.             actionListener.actionPerformed(e);
  850.         }
  851.     }
  852.  
  853.     /**
  854.      * Returns the parameter string representing the state of this 
  855.      * scrolling list. This string is useful for debugging. 
  856.      * @return    the parameter string of this scrolling list. 
  857.      * @since     JDK1.0
  858.      */
  859.     protected String paramString() {
  860.     return super.paramString() + ",selected=" + getSelectedItem();
  861.     }
  862.  
  863.     /**
  864.      * @deprecated As of JDK version 1.1,
  865.      * Not for public use in the future.
  866.      * This method is expected to be retained only as a package
  867.      * private method.
  868.      */
  869.     public synchronized void delItems(int start, int end) {
  870.     for (int i = end; i >= start; i--) {
  871.         items.removeElementAt(i);
  872.     }
  873.     ListPeer peer = (ListPeer)this.peer;
  874.     if (peer != null) {
  875.         peer.delItems(start, end);
  876.     }
  877.     }
  878.  
  879.     /* 
  880.      * Serialization support.  Since the value of the selected
  881.      * field isn't neccessarily up to date we sync it up with the 
  882.      * peer before serializing.
  883.      */
  884.  
  885.     private int listSerializedDataVersion = 1;
  886.  
  887.  
  888.     private void writeObject(ObjectOutputStream s)
  889.       throws IOException 
  890.     {
  891.       synchronized (this) {
  892.     ListPeer peer = (ListPeer)this.peer;
  893.     if (peer != null) {
  894.       selected = peer.getSelectedIndexes();
  895.     }
  896.       }
  897.       s.defaultWriteObject();
  898.  
  899.       AWTEventMulticaster.save(s, itemListenerK, itemListener);
  900.       AWTEventMulticaster.save(s, actionListenerK, actionListener);
  901.       s.writeObject(null);
  902.     }
  903.  
  904.  
  905.     private void readObject(ObjectInputStream s)
  906.       throws ClassNotFoundException, IOException 
  907.     {
  908.       s.defaultReadObject();
  909.  
  910.       Object keyOrNull;
  911.       while(null != (keyOrNull = s.readObject())) {
  912.     String key = ((String)keyOrNull).intern();
  913.  
  914.     if (itemListenerK == key) 
  915.       addItemListener((ItemListener)(s.readObject()));
  916.  
  917.     else if (actionListenerK == key) 
  918.       addActionListener((ActionListener)(s.readObject()));
  919.  
  920.     else // skip value for unrecognized key
  921.       s.readObject();
  922.       }
  923.     }
  924.  
  925.  
  926. }
  927.